package org.facyt.commons.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;

/**
 * Servlet de vaadin integrado con spring.
 * 
 */
public class SpringApplicationServlet extends AbstractApplicationServlet {

	private static final long serialVersionUID = -3204119654788157619L;

	public static final String APPLICATION_BEAN_NAME = "applicationBeanName";

	private WebApplicationContext applicationContext;

	private String applicationBeanName;

	private Class<? extends Application> applicationClass;

	@SuppressWarnings("unchecked")
	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		super.init(servletConfig);

		log("Inicializando el conexto de spring con vaadin");
		applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletConfig.getServletContext());

		applicationBeanName = servletConfig.getInitParameter(APPLICATION_BEAN_NAME);
		
		if (applicationBeanName.isEmpty()) {
			throw new ServletException("El parametro applicationBeanName debe ser definido como parametro del servlet.");
		}

		if (!applicationContext.containsBean(applicationBeanName)) {
			throw new ServletException("El bean " + applicationBeanName + " no esta definido en el contexto de spring.");
		}

		final Class<?> class1 = applicationContext.getType(applicationBeanName);
		if (Application.class.isAssignableFrom(class1)) {
			this.applicationClass = (Class<? extends Application>) class1;
		} else {
			throw new ServletException("El bean " + applicationBeanName + " no es subclase de com.vaadin.Application. (" + class1 + ")");
		}
		
	}

	@Override
	protected Application getNewApplication(HttpServletRequest request) throws ServletException {
		try {
			return applicationContext.getBean(getApplicationBeanName(), getApplicationClass());
		} catch (ClassNotFoundException e) {
			throw new ServletException("getNewApplication failed", e);
		}
	}

	@Override
	protected Class<? extends Application> getApplicationClass() throws ClassNotFoundException {
		return applicationClass;
	}

	public String getApplicationBeanName() {
		return applicationBeanName;
	}

}